package com.dlc.shop.api.manager;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.dlc.shop.bean.app.dto.*;
import com.dlc.shop.bean.app.param.OrderShopParam;
import com.dlc.shop.bean.app.param.SubmitOrderParam;
import com.dlc.shop.bean.dto.UserScoreLockDTO;
import com.dlc.shop.bean.enums.*;
import com.dlc.shop.bean.event.SubmitOrderActivityEvent;
import com.dlc.shop.bean.event.TryLockStockEvent;
import com.dlc.shop.bean.model.Order;
import com.dlc.shop.bean.model.OrderItem;
import com.dlc.shop.bean.vo.EsProdUpdateVO;
import com.dlc.shop.bean.vo.SkuStockVO;
import com.dlc.shop.bean.vo.VirtualRemarkVO;
import com.dlc.shop.common.config.Constant;
import com.dlc.shop.common.constants.OrderCacheNames;
import com.dlc.shop.common.constants.SegmentIdKey;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.i18n.I18nMessage;
import com.dlc.shop.common.response.ResponseEnum;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.CacheManagerUtil;
import com.dlc.shop.common.util.RedisUtil;
import com.dlc.shop.coupon.common.dto.CouponRecordDTO;
import com.dlc.shop.coupon.common.service.CouponUseRecordService;
import com.dlc.shop.manager.SubmitOrderManager;
import com.dlc.shop.service.SegmentService;
import com.dlc.shop.service.SkuStockLockService;
import com.dlc.shop.user.common.service.UserScoreLockService;
import lombok.AllArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * 提交订单适配
 * @author FrozenWatermelon
 * @date 2020/12/07
 */
@Component
@AllArgsConstructor
public class SubmitOrderImplManager implements SubmitOrderManager {

    private final CacheManagerUtil cacheManagerUtil;

    private final UserScoreLockService userScoreLockService;

    private final SkuStockLockService skuStockLockService;

    private final SegmentService segmentService;

    private final CouponUseRecordService couponLockService;

    private final ApplicationContext applicationContext;


    @Override
    public ServerResponseEntity<ShopCartOrderMergerDto> checkSubmitInfo(SubmitOrderParam submitOrderParam, String userId) {
        ShopCartOrderMergerDto mergerOrder = cacheManagerUtil.getCache(OrderCacheNames.ORDER_CONFIRM_KEY, String.valueOf(userId));
        // 看看订单有没有过期
        if (Objects.isNull(mergerOrder)) {
            // 订单已过期，请重新下单
            throw new YamiShopBindException("yami.order.expired");
        }
        // 如果是快递配送，判断用户地址是否不在配送范围内
        checkExpressDvyType(mergerOrder);
        // 检查下活动有没有过期
        applicationContext.publishEvent(new SubmitOrderActivityEvent(mergerOrder));
        if (CollectionUtil.isNotEmpty(submitOrderParam.getOrderInvoiceList())) {
            mergerOrder.setOrderInvoiceList(submitOrderParam.getOrderInvoiceList());
        }
        // 同城自提判断
        checkSameAndStationDvyType(mergerOrder, submitOrderParam);
        // 检查下虚拟商品的所需留言是否填写完成
        checkVirtualRemark(mergerOrder, submitOrderParam);
        // 防止重复、同时提交
        boolean cad = RedisUtil.cad(OrderCacheNames.ORDER_CONFIRM_UUID_KEY + OrderCacheNames.UNION + userId, userId);
        if (!cad) {
            // 订单状态已经发生改变，请重新下单
            OrderNumbersDto orderNumbersDto = new OrderNumbersDto(null);
            orderNumbersDto.setDuplicateError(1);
            return ServerResponseEntity.fail(ResponseEnum.REPEAT_ORDER);
        }
        // 看看订单的标记有没有过期
        if (cacheManagerUtil.getCache(OrderCacheNames.ORDER_CONFIRM_KEY, userId) == null) {
            // 订单已过期，请重新下单
            throw new YamiShopBindException("yami.order.expired");
        }
        mergerOrder.setUserId(userId);
        mergerOrder.setVirtualRemarkList(submitOrderParam.getVirtualRemarkList());
        // 设置自提信息
        mergerOrder.setOrderSelfStationDto(submitOrderParam.getOrderSelfStationDto());
        // 订单拆单
        // 需要拆分订单(订单类型为普通订单才需要拆单)
        if (needSplitShopCartOrder(mergerOrder)) {
            // 组合商品处理及虚拟商品拆分订单
            splitShopCartOrderDtoByComboAndVirtual(mergerOrder);
        }
        // 设置备注和生成订单id
        setOrderRemarkAndId(mergerOrder, submitOrderParam);
        return ServerResponseEntity.success(mergerOrder);
    }

    private void checkExpressDvyType(ShopCartOrderMergerDto mergerOrder){
        if (mergerOrder.getDvyTypes().get(0).getDvyType().equals(DeliveryType.EXPRESS.getValue())) {
            for (ShopCartOrderDto shopCartOrder : mergerOrder.getShopCartOrders()) {
                for (ShopCartItemDiscountDto discount : shopCartOrder.getShopCartItemDiscounts()) {
                    for (ShopCartItemDto shopCartItem : discount.getShopCartItems()) {
                        if (!shopCartItem.getIsDelivery()) {
                            // 当前区域不支持配送
                            throw new YamiShopBindException(ResponseEnum.DELIVERY_OVER, "yami.delivery.over");
                        }
                    }
                }
            }
        }
    }

    private void checkSameAndStationDvyType(ShopCartOrderMergerDto mergerOrder, SubmitOrderParam submitOrderParam){
        Map<Long, Integer> dvyMap = mergerOrder.getDvyTypes().stream().collect(Collectors.toMap(DvyTypeDTO::getShopId, DvyTypeDTO::getDvyType));
        for (ShopCartOrderDto cartOrder : mergerOrder.getShopCartOrders()) {
            if (Objects.equals(dvyMap.get(cartOrder.getShopId()), DvyType.SAME_CITY.value())) {
                if (Objects.nonNull(cartOrder.getShopCityStatus()) && Objects.equals(cartOrder.getShopCityStatus(), ShopCityStatus.NO_CONFIG.value())) {
                    // 当前店铺未开启同城配送
                    throw new YamiShopBindException("yami.order.same.city.error");
                }
                if (Objects.nonNull(cartOrder.getShopCityStatus()) && cartOrder.getShopCityStatus() < ShopCityStatus.USABLE.value()) {
                    // 超出商家配送距离或起送费不够
                    throw new YamiShopBindException("yami.order.same.city.error2");
                }
            }
            if (Objects.equals(dvyMap.get(cartOrder.getShopId()), DvyType.STATION.value()) && Objects.isNull(mergerOrder.getStationId()) && Objects.isNull(submitOrderParam.getOrderSelfStationDto())) {
                // 请选择自提点并填写完整的自提信息
                throw new YamiShopBindException("yami.station.detail.check");
            }
        }

    }

    private void checkVirtualRemark(ShopCartOrderMergerDto mergerOrder, SubmitOrderParam submitOrderParam){
        if (Objects.equals(mergerOrder.getMold(), 1) && CollectionUtil.isNotEmpty(submitOrderParam.getVirtualRemarkList())) {
            List<VirtualRemarkVO> virtualRemarkList = submitOrderParam.getVirtualRemarkList();
            boolean isRequired = false;
            for (VirtualRemarkVO virtualRemarkVO : mergerOrder.getVirtualRemarkList()) {
                if (virtualRemarkVO.getIsRequired()) {
                    isRequired = true;
                    break;
                }
            }
            // 如果至少要输入一个备注信息，则不能为空
            if (isRequired && CollectionUtil.isEmpty(virtualRemarkList)) {
                // 不能为空
                throw new YamiShopBindException("yami.order.not.null");
            }
            for (VirtualRemarkVO virtualRemarkVO : virtualRemarkList) {
                if (virtualRemarkVO.getIsRequired() && StrUtil.isBlank(virtualRemarkVO.getValue())) {
                    // 不能为空
                    throw new YamiShopBindException("yami.order.not.null");
                }
            }
        }
    }

    private void setOrderRemarkAndId(ShopCartOrderMergerDto mergerOrder, SubmitOrderParam submitOrderParam){
        List<OrderShopParam> orderParams = submitOrderParam.getOrderShopParams();
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            if (CollectionUtil.isNotEmpty(orderParams)) {
                for (OrderShopParam orderParam : orderParams) {
                    if (!Objects.equals(shopCartOrder.getShopId(), orderParam.getShopId())) {
                        continue;
                    }
                    shopCartOrder.setRemarks(orderParam.getRemarks());
                }
            }
        }
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            // 使用雪花算法生成的订单号
            String orderNumber = segmentService.getDateFormatSegmentId(SegmentIdKey.ORDER).toString();
            shopCartOrder.setOrderNumber(orderNumber);
        }
    }

    @Override
    @EventListener(TryLockStockEvent.class)
    public void tryLockStock(TryLockStockEvent event) {
        if (Objects.equals(event.getMergerOrder().getOrderType(),OrderType.SECKILL)) {
            return;
        }
        List<ShopCartOrderDto> shopCartOrders = event.getMergerOrder().getShopCartOrders();
        List<Order> orders = new ArrayList<>();
        List<SkuStockVO> skuStockList = new ArrayList<>();
        // 避免因赠品，套餐重复
        Map<Long,SkuStockVO> skuStockMap = new HashMap<>(16);
        // 生成订单详情和赠品处理
        createItemAndGiveawayItem(shopCartOrders, orders, skuStockMap);
        Map<Long, EsProdUpdateVO> prodMap = new HashMap<>(skuStockMap.size());
        // 添加赠品库存扣减项
        for (Long skuId : skuStockMap.keySet()) {
            SkuStockVO skuStockVO = skuStockMap.get(skuId);
            skuStockList.add(skuStockMap.get(skuId));

            // 统计商品的购买数量--用于es更新商品库存
            EsProdUpdateVO prodUpdateVO = prodMap.get(skuStockVO.getProdId());
            if (Objects.isNull(prodUpdateVO)) {
                prodUpdateVO = new EsProdUpdateVO();
                prodUpdateVO.setProdId(skuStockVO.getProdId());
                // 减少商品库存
                prodUpdateVO.setType(0);
                prodUpdateVO.setCount(0);
                prodMap.put(skuStockVO.getProdId(), prodUpdateVO);
            }
            prodUpdateVO.setCount(prodUpdateVO.getCount() + skuStockVO.getStock());
        }
        event.setProdList(new ArrayList<>(prodMap.values()));
        // 锁定库存
        ServerResponseEntity<?> lockStockResponse = skuStockLockService.lock(skuStockList, shopCartOrders);
        // 提示具体哪个商品库存不足
        if (Objects.equals(ResponseEnum.NOT_STOCK.value(), lockStockResponse.getCode())) {
            for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
                List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
                Long skuId = Long.parseLong(lockStockResponse.getData().toString());
                for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                    List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();
                    for (ShopCartItemDto orderItem : shopCartItems) {
                        if (Objects.equals(orderItem.getMold(), ProdMoldEnum.COMBO.value())) {
                            for (ShopCartItemDto comboShopCartItem : orderItem.getComboShopCartItems()) {
                                prodNotStockException(orderItem, comboShopCartItem.getSkuId(), skuId);
                            }
                        }
                        prodNotStockException(orderItem, orderItem.getSkuId(), skuId);
                    }
                }
            }
        }
        if (!lockStockResponse.isSuccess()) {
            throw new YamiShopBindException(ResponseEnum.EXCEPTION);
        }
    }

    private static void prodNotStockException(ShopCartItemDto orderItem, Long skuId, Long errorSkuId) {
        if (Objects.equals(skuId, errorSkuId)) {
            // 拼接库存不足商品的名称（有规格sku，要把规格也拼接上）
            // split(" ")[0]是因为有些商品名已经拼接了‘prodName skuName’，只取prodName，避免skuName重复
            // 有些商品名已经拼接了‘prodName skuName’，只取prodName，避免skuName重复
            String prodName;
           // if (ObjectUtils.isEmpty(prodName = orderItem.getSkuName())) {
            //    prodName = orderItem.getProdName().split(" ")[0];
            if (ObjectUtils.isEmpty(orderItem.getSkuName())
                        || orderItem.getProdName().contains(orderItem.getSkuName())) {
                    prodName = orderItem.getProdName();
                } else {
                   // prodName = orderItem.getProdName().split(" ")[0] + "(" + prodName + ")";
                    prodName = orderItem.getProdName() + "(" + orderItem.getSkuName() + ")";
                }
                throw new YamiShopBindException('[' + prodName + ']' + I18nMessage.getMessage("yami.insufficient.inventory.area"));
            }

        }


    private void createItemAndGiveawayItem(List<ShopCartOrderDto> shopCartOrders, List<Order> orders, Map<Long, SkuStockVO> skuStockMap) {
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            Order order = new Order();
            order.setShopId(shopCartOrder.getShopId());
            order.setOrderNumber(shopCartOrder.getOrderNumber());
            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrder.getShopCartItemDiscounts();
            List<OrderItem> orderItems = new ArrayList<>();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();
                for (ShopCartItemDto orderItem : shopCartItems) {
                    if(Objects.equals(orderItem.getMold(),ProdMoldEnum.COMBO.value())){
                        // 组合商品主商品增加锁定库存数量，用于支付后增加销量
                        handleSkuStock(skuStockMap, shopCartOrder, orderItem);
                        SkuStockVO skuStockVO = skuStockMap.get(orderItem.getSkuId());
                        // 组合商品操作总库存即可，不需要处理区域库存，库存id为0代表是组合商品的主商品
                        skuStockVO.setStockPointId(0L);
                        for (ShopCartItemDto comboShopCartItem : orderItem.getComboShopCartItems()) {
                            handleSkuStock(skuStockMap, shopCartOrder, comboShopCartItem);
                        }
                        continue;
                    }
                    OrderItem item = new OrderItem();
                    item.setProdId(orderItem.getProdId());
                    item.setSkuId(orderItem.getSkuId());
                    item.setStatus(-1);
                    item.setProdCount(orderItem.getProdCount());
                    item.setStockPointId(orderItem.getStockPointId());
                    item.setStockPointType(orderItem.getStockPointType());
                    orderItems.add(item);
                    handleSkuStock(skuStockMap, shopCartOrder, orderItem);
                    if (CollUtil.isEmpty(orderItem.getGiveawayShopCartItemList())) {
                        continue;
                    }
                    // 赠品库存计算
                    int productNums = shopCartOrder.getTotalCount();
                    for (ShopCartItemDto giveawayShopCartItem : orderItem.getGiveawayShopCartItemList()) {
                        // 出入库用到的信息
                        OrderItem giveawayItem = new OrderItem();
                        giveawayItem.setProdId(giveawayShopCartItem.getProdId());
                        giveawayItem.setSkuId(giveawayShopCartItem.getSkuId());
                        giveawayItem.setStatus(-1);
                        giveawayItem.setProdCount(giveawayShopCartItem.getProdCount());
                        orderItems.add(giveawayItem);
                        productNums = productNums + orderItem.getProdCount();
                        // 判断是否重复.重复重新put
                        SkuStockVO skuStockLock;
                        if(skuStockMap.containsKey(giveawayShopCartItem.getSkuId())){
                            skuStockLock = skuStockMap.get(giveawayShopCartItem.getSkuId());
                            skuStockLock.setStock(skuStockLock.getStock() + giveawayShopCartItem.getProdCount());
                        } else {
                            skuStockLock = new SkuStockVO(shopCartOrder.getOrderNumber(), giveawayShopCartItem.getSkuId(), giveawayShopCartItem.getProdCount(), giveawayShopCartItem.getStockPointId());
                            skuStockLock.setProdId(giveawayShopCartItem.getProdId());
                        }
                        skuStockMap.put(giveawayShopCartItem.getSkuId(), skuStockLock);
                    }
                }
            }
            order.setOrderItems(orderItems);
            orders.add(order);
        }
    }

    @Override
    @EventListener(TryLockStockEvent.class)
    public void tryLockCoupon(TryLockStockEvent event) {
        ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
        String userId = event.getUserId();
        if (!Objects.equals(mergerOrder.getOrderType(), OrderType.ORDINARY)) {
            return;
        }
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        List<String> orderNumbers = new ArrayList<>();

        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            String orderNumber = shopCartOrder.getOrderNumber();
            List<CouponOrderDto> coupons = shopCartOrder.getCoupons();
            if (CollectionUtil.isNotEmpty(coupons)) {
                for (CouponOrderDto coupon : coupons) {
                    if (Objects.equals(Boolean.TRUE, coupon.isChoose())) {
                        coupon.setOrderNumber(orderNumber);
                    }
                }
            }
            orderNumbers.add(orderNumber);
        }

        // 锁优惠券
        List<CouponRecordDTO> lockCouponParams = getLockCouponDto(mergerOrder, orderNumbers);
        if (CollectionUtil.isNotEmpty(lockCouponParams)) {
            couponLockService.lockCoupon(lockCouponParams,userId);
        }
    }

    /**
     * 尝试锁定优惠券
     * @param mergerOrder
     * @param orderIds
     */
    private List<CouponRecordDTO> getLockCouponDto(ShopCartOrderMergerDto mergerOrder, List<String> orderIds) {
        // 锁定优惠券
        // 平台优惠券
        List<CouponRecordDTO> lockCouponParams = new ArrayList<>();
        CouponRecordDTO platformLockCouponParam = getLockCouponDTO(mergerOrder.getCoupons());
        if (platformLockCouponParam != null) {
            // 平台优惠券涉及多个订单，所以设置订单id为多个订单id以逗号分割
            platformLockCouponParam.setOrderNumbers(StrUtil.join(StrUtil.COMMA, orderIds));
            lockCouponParams.add(platformLockCouponParam);
        }
        // 店铺优惠券
        for (ShopCartOrderDto shopCartOrder : mergerOrder.getShopCartOrders()) {
            CouponRecordDTO shopLockCouponParam = getLockCouponDTO(shopCartOrder.getCoupons());
            if (shopLockCouponParam != null) {
                lockCouponParams.add(shopLockCouponParam);
            }
        }

        return lockCouponParams;
    }

    private CouponRecordDTO getLockCouponDTO(List<CouponOrderDto> couponOrders) {
        if (CollectionUtil.isEmpty(couponOrders)) {
            return null;
        }
        for (CouponOrderDto couponOrder : couponOrders) {
            if ((Objects.equals(Boolean.TRUE, couponOrder.isChoose())) && couponOrder.isCanUse()) {
                CouponRecordDTO param = new CouponRecordDTO();
                param.setOrderNumbers(couponOrder.getOrderNumber());
                param.setCouponId(couponOrder.getCouponId());
                param.setCouponUserId(couponOrder.getCouponUserId());
                param.setReduceAmount(couponOrder.getReduceAmount());
                return param;
            }
        }
        return null;
    }

    @Override
    @EventListener(TryLockStockEvent.class)
    public void tryLockScore(TryLockStockEvent event) {
        String userId = event.getUserId();
        ShopCartOrderMergerDto mergerOrder = event.getMergerOrder();
        // 如果没有使用积分，就不用锁定积分啦
        if (Objects.isNull(mergerOrder.getUsableScore()) || Objects.equals(mergerOrder.getUsableScore(), 0L)) {
            return;
        }
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        List<UserScoreLockDTO> userScoreLocks = new ArrayList<>();
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            if (Objects.equals(shopCartOrder.getUseScore(), 0L)) {
                continue;
            }
            userScoreLocks.add(new UserScoreLockDTO(shopCartOrder.getOrderNumber(), shopCartOrder.getUseScore(), mergerOrder.getOrderType().value()));
        }

        // 锁定积分
        userScoreLockService.lock(userScoreLocks,userId);
    }

    private void splitShopCartOrderDtoByComboAndVirtual(ShopCartOrderMergerDto mergerOrder) {
        List<ShopCartOrderDto> vitrualShopCartOrders = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<ShopCartOrderDto> normalShopCartOrderList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (ShopCartOrderDto shopCartOrder : mergerOrder.getShopCartOrders()) {
            double levelFreeTransfee = Objects.isNull(shopCartOrder.getPlatformFreeFreightAmount()) ? 0L : shopCartOrder.getPlatformFreeFreightAmount();
             Iterator<ShopCartItemDiscountDto> shopCartIterator = shopCartOrder.getShopCartItemDiscounts().iterator();
            double transFee = shopCartOrder.getTransFee();
            List<ShopCartOrderDto> virtualShopCartOrderList = new ArrayList<>();
            List<ShopCartItemDto> normalShopCartItemList = new ArrayList<>(Constant.INITIAL_CAPACITY);
            int itemCount = shopCartOrder.getShopCartItemDiscounts().get(0).getShopCartItems().size();
            // 如果当前店铺的商品数量为1,则不需要拆单直接跳过
            if(itemCount == 1 && shopCartOrder.getShopCartItemDiscounts().size() == 1){
                ShopCartItemDto shopCartItemDto = shopCartOrder.getShopCartItemDiscounts().get(0).getShopCartItems().get(0);
                if (Objects.equals(shopCartItemDto.getMold(), ProdMoldEnum.VIRTUAL.value())) {
                    ShopCartOrderDto shopCartOrderVO = getVirtualShopCartOrgetder(shopCartOrder, shopCartItemDto);
                    virtualShopCartOrderList.add(shopCartOrderVO);
                }else{
                    // 普通的商品放入同一个list
                    normalShopCartItemList.add(shopCartItemDto);
                }
            }else {
                while (shopCartIterator.hasNext()) {
                    ShopCartItemDiscountDto shopCartItemDiscountDto = shopCartIterator.next();
                    Iterator<ShopCartItemDto> iterator = shopCartItemDiscountDto.getShopCartItems().iterator();
                    while (iterator.hasNext()) {
                        ShopCartItemDto shopCartItemDto = iterator.next();
                        // 普通虚拟商品直接拆分即可
                        if (Objects.equals(shopCartItemDto.getMold(), ProdMoldEnum.VIRTUAL.value())) {
                            ShopCartOrderDto shopCartOrderVO = getVirtualShopCartOrgetder(shopCartOrder, shopCartItemDto);
                            virtualShopCartOrderList.add(shopCartOrderVO);
                        } else {
                            // 普通的商品放入同一个list
                            normalShopCartItemList.add(shopCartItemDto);
                        }
                    }
                }
            }
            // 重新算一下商品
            if (CollectionUtil.isNotEmpty(virtualShopCartOrderList)) {
                for (ShopCartOrderDto shopCartOrderVO : virtualShopCartOrderList) {
                    // 店铺订单计算
                    // 能被拆分的都是虚拟商品,运费都为0
                    shopCartOrderVO.setTransFee(0.0);
                    shopCartOrderVO.setPlatformFreeFreightAmount(0.0);
                    loadShopCartOrderDto(shopCartOrderVO);
                    vitrualShopCartOrders.add(shopCartOrderVO);
                }
            }
            // 普通商品在一个order
            if (CollectionUtil.isNotEmpty(normalShopCartItemList)) {
                ShopCartItemDiscountDto shopCartItemDiscount = new ShopCartItemDiscountDto();
                shopCartItemDiscount.setShopCartItems(normalShopCartItemList);
                shopCartOrder.setShopCartItemDiscounts(Collections.singletonList(shopCartItemDiscount));
                shopCartOrder.setTransFee(transFee);
                shopCartOrder.setPlatformFreeFreightAmount(Math.min(levelFreeTransfee, shopCartOrder.getTransFee()));
                loadShopCartOrderDto(shopCartOrder);
                normalShopCartOrderList.add(shopCartOrder);
            }
        }
        mergerOrder.setShopCartOrders(new ArrayList<>(Constant.INITIAL_CAPACITY));
        if (CollectionUtil.isNotEmpty(normalShopCartOrderList)) {
            mergerOrder.setShopCartOrders(normalShopCartOrderList);
        }
        if (CollUtil.isNotEmpty(vitrualShopCartOrders)) {
            mergerOrder.getShopCartOrders().addAll(vitrualShopCartOrders);
        }
    }
    private void loadShopCartOrderDto(ShopCartOrderDto shopCartOrderVO) {
        if (Objects.isNull(shopCartOrderVO.getPlatformFreeFreightAmount())) {
            shopCartOrderVO.setPlatformFreeFreightAmount(0.0);
        }
        if (Objects.isNull(shopCartOrderVO.getTransFee())) {
            shopCartOrderVO.setTransFee(0.0);
        }
        shopCartOrderVO.setUseScore(0L);
        shopCartOrderVO.setActualTotal(shopCartOrderVO.getTransFee() - shopCartOrderVO.getPlatformFreeFreightAmount());
        shopCartOrderVO.setTotal(0.0);
        shopCartOrderVO.setTotalCount(0);
        shopCartOrderVO.setDiscountReduce(0.0);
        shopCartOrderVO.setCouponReduce(0.0);
        shopCartOrderVO.setPlatformCouponReduce(0.0);
        shopCartOrderVO.setScoreReduce(0.0);
        shopCartOrderVO.setPlatformAmount(shopCartOrderVO.getPlatformFreeFreightAmount());
        shopCartOrderVO.setLevelReduce(0.0);
        shopCartOrderVO.setShopReduce(shopCartOrderVO.getPlatformAmount());
        shopCartOrderVO.setPlatformCommission(0.0);
        List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrderVO.getShopCartItemDiscounts();
        for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
            for (ShopCartItemDto cartItemDto : shopCartItemDiscount.getShopCartItems()) {
                // 订单项的金额在生成订单时已经算好了，这里只需要相加即可，不需要别的处理
                shopCartOrderVO.setActualTotal(shopCartOrderVO.getActualTotal() + cartItemDto.getActualTotal());
                shopCartOrderVO.setTotal(shopCartOrderVO.getTotal() + cartItemDto.getProductTotalAmount());
                shopCartOrderVO.setTotalCount(shopCartOrderVO.getTotalCount() + cartItemDto.getProdCount());
                shopCartOrderVO.setShopReduce(shopCartOrderVO.getShopReduce() + cartItemDto.getShareReduce());
                cartItemDto.setPlatformCommission(Objects.isNull(cartItemDto.getPlatformCommission()) ? 0L : cartItemDto.getPlatformCommission());
                shopCartOrderVO.setPlatformCommission(shopCartOrderVO.getPlatformCommission() + cartItemDto.getPlatformCommission());
                if (Objects.nonNull(cartItemDto.getDiscountAmount())) {
                    shopCartOrderVO.setDiscountReduce(shopCartOrderVO.getDiscountReduce() + cartItemDto.getDiscountAmount());
                }
                if (Objects.nonNull(cartItemDto.getShopCouponAmount())) {
                    shopCartOrderVO.setCouponReduce(shopCartOrderVO.getCouponReduce() + cartItemDto.getShopCouponAmount());
                }
                if (Objects.nonNull(cartItemDto.getPlatformCouponAmount())) {
                    shopCartOrderVO.setPlatformCouponReduce(shopCartOrderVO.getPlatformCouponReduce() + cartItemDto.getPlatformCouponAmount());
                }
                if (Objects.nonNull(cartItemDto.getScorePayReduce())) {
                    shopCartOrderVO.setScoreReduce(shopCartOrderVO.getScoreReduce() + cartItemDto.getScorePayReduce());
                }
                if (Objects.nonNull(cartItemDto.getPlatformShareReduce())) {
                    shopCartOrderVO.setPlatformAmount(shopCartOrderVO.getPlatformAmount() + cartItemDto.getPlatformShareReduce());
                }
                if (Objects.nonNull(cartItemDto.getLevelReduce())) {
                    shopCartOrderVO.setLevelReduce(shopCartOrderVO.getLevelReduce() + cartItemDto.getLevelReduce());
                }
                if (Objects.nonNull(cartItemDto.getScorePrice())) {
                    shopCartOrderVO.setUseScore(shopCartOrderVO.getUseScore() + cartItemDto.getScorePrice());
                }
            }
        }
    }

    private ShopCartOrderDto getVirtualShopCartOrgetder(ShopCartOrderDto shopCartOrder, ShopCartItemDto shopCartItemDto) {
        ShopCartOrderDto shopCartOrderVO = new ShopCartOrderDto();
        // 拆分虚拟商品
        shopCartOrderVO.setShopId(shopCartOrder.getShopId());
        shopCartOrderVO.setShopName(shopCartOrder.getShopName());
        shopCartOrderVO.setRemarks(shopCartOrder.getRemarks());
        shopCartOrderVO.setDvyType(DeliveryType.NO_EXPRESS.getValue());
        shopCartOrderVO.setShopCartItemDiscounts(new ArrayList<>(Constant.INITIAL_CAPACITY));
        ShopCartItemDiscountDto shopCartItemDiscount = new ShopCartItemDiscountDto();
        shopCartItemDiscount.setShopCartItems(Collections.singletonList(shopCartItemDto));
        shopCartOrderVO.getShopCartItemDiscounts().add(shopCartItemDiscount);
        return shopCartOrderVO;
    }

    /**
     * 是否需要拆单
     * 1.含有虚拟商品需要拆单
     *
     * @param mergerOrder
     * @return
     */
    private boolean needSplitShopCartOrder(ShopCartOrderMergerDto mergerOrder) {
        // 普通订单和团购才需要拆单
        if (!Objects.equals(mergerOrder.getOrderType().value(), OrderType.ORDINARY.value())) {
            return Boolean.FALSE;
        }
        int orderItemCount = 0;
        boolean hasVirtualProd = false;
        for (ShopCartOrderDto shopCartOrder : mergerOrder.getShopCartOrders()) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                orderItemCount += shopCartItemDiscount.getShopCartItems().size();
                // 供应商需要拆单
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    // 判断下是否为虚拟商品,如果是虚拟商品且多于一个商品项时进行拆单
                    if (Objects.nonNull(shopCartItem.getMold()) && Objects.equals(shopCartItem.getMold(), ProdMoldEnum.VIRTUAL.value())) {
                        hasVirtualProd = Boolean.TRUE;
                        break;
                    }
                }
            }
        }
        return orderItemCount > 1 && hasVirtualProd;
    }

    private static void handleSkuStock(Map<Long, SkuStockVO> stockMap, ShopCartOrderDto shopCartOrder, ShopCartItemDto orderItem) {
        SkuStockVO skuStockVO = stockMap.get(orderItem.getSkuId());
        if (Objects.isNull(skuStockVO)) {
            skuStockVO = new SkuStockVO(
                    shopCartOrder.getOrderNumber(),
                    orderItem.getSkuId(),
                    0,
                    orderItem.getStockPointId()
            );
            skuStockVO.setProdId(orderItem.getProdId());
            stockMap.put(orderItem.getSkuId(), skuStockVO);
        }
        skuStockVO.setStock(skuStockVO.getStock() + orderItem.getProdCount());
    }
}
